/*
  This file is part of 'Trivial chess'.

  'Trivial chess' is free software: you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.

  'Trivial chess' is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with 'Trivial chess'.  If not, see <http://www.gnu.org/licenses/>.
*/

/* SVN FILE: $Id$ */
/**
 * @author         $Author$
 * @version        $Rev$
 * @lastrevision   $Date$
 * @filesource     $URL$
 */

#ifndef ORDABSTRACT_H_
#define ORDABSTRACT_H_

#include <boost/cstdint.hpp>

template<class Enum, class Fst, class Scd, typename Int, int n>
class OrdAbstract {
public:
	static const Enum NIL() {
		return Enum(Enum::COUNT);
	}
	static const Enum END()  {
		return Enum::NIL();
	}
	static const Enum REND() {
		return Enum(-1);
	}

public:
	OrdAbstract() {}

	explicit OrdAbstract(const Int _enum) : _enum(_enum) {}

	OrdAbstract(const Fst fst, const Scd scd)
		: _enum(fst.toInt() | scd.toInt() << n) {}

	const Int toInt() const {
		return this->_enum;
	}

	void fromInt(const Int _enum) {
		this->_enum = _enum;
	}

	Enum operator++() {
		return Enum(++this->_enum);
	}

	Enum operator--() {
		return Enum(--this->_enum);
	}

	bool operator==(const Enum _enum) const {
		return  this->_enum == _enum._enum;
	}

	const Fst fst() const {
		return Fst(this->_enum & ((1 << n) - 1));
	}

	const Scd scd() const {
		return Scd(this->_enum >> n);
	}

	void setFst(const Fst fst) {
		this->_enum &= ~((1 << n) - 1);
		this->_enum |= fst.toInt();
	}

	void setScd(const Scd scd) {
		this->_enum &= (1 << n) - 1;
		this->_enum |= scd.toInt() << n;
	}
private:
	Int _enum;
};



#endif /* ORDABSTRACT_H_ */
